#include <stdio.h>
#include <stdlib.h>
#include <math.h>




typedef struct tagBITMAPFILEHEADER
{
    short bfType;
    int bfSize;
    int bfReserved;
    int bfOffBits;

} BITMAPFILEHEADER;

typedef struct tagBITMAPINFOHEADER
{
    int biSize;
    int biWidth;
    int biHeight;
    short biPlanes;
    short biBitCount;
    short biCompression;
    int biSizeImage;
    int biXPelsPerMeter;
    int biYPelsPerMeter;
    int biClrUsed;
    int biClrImportant;

} BITMAPINFOHEADER;

int readinfo(FILE *fp1,FILE *fp2,int mode){

    BITMAPFILEHEADER fhdr;
    BITMAPINFOHEADER ihdr;
    int dataSize;

    fread(&fhdr.bfType,2,1,fp1);
    fread(&fhdr.bfSize,4,1,fp1);
    fread(&fhdr.bfReserved,4,1,fp1);
    fread(&fhdr.bfOffBits,4,1,fp1);

    dataSize = fhdr.bfSize - fhdr.bfOffBits;


    if(mode){
        fwrite(&fhdr.bfType,2,1,fp2);
        fwrite(&fhdr.bfSize,4,1,fp2);
        fwrite(&fhdr.bfReserved,4,1,fp2);
        fwrite(&fhdr.bfOffBits,4,1,fp2);
    }else {
        printf("File size infos:\n");
        printf("- file size:        %d bytes \n",fhdr.bfSize);
        printf("- file head size:   %d bytes \n",fhdr.bfOffBits);
        printf("- file data size:   %d bytes \n",dataSize);
    }

    fread(&ihdr.biSize,4,1,fp1);
    fread(&ihdr.biWidth,4,1,fp1);
    fread(&ihdr.biHeight,4,1,fp1);
    fread(&ihdr.biPlanes,2,1,fp1);
    fread(&ihdr.biBitCount,2,1,fp1);
    fread(&ihdr.biCompression,4,1,fp1);
    fread(&ihdr.biSizeImage,4,1,fp1);
    fread(&ihdr.biXPelsPerMeter,4,1,fp1);
    fread(&ihdr.biYPelsPerMeter,4,1,fp1);
    fread(&ihdr.biClrUsed,4,1,fp1);
    fread(&ihdr.biClrImportant,4,1,fp1);

    if(mode){
        fwrite(&ihdr.biSize,4,1,fp2);
        fwrite(&ihdr.biWidth,4,1,fp2);
        fwrite(&ihdr.biHeight,4,1,fp2);
        fwrite(&ihdr.biPlanes,2,1,fp2);
        fwrite(&ihdr.biBitCount,2,1,fp2);
        fwrite(&ihdr.biCompression,4,1,fp2);
        fwrite(&ihdr.biSizeImage,4,1,fp2);
        fwrite(&ihdr.biXPelsPerMeter,4,1,fp2);
        fwrite(&ihdr.biYPelsPerMeter,4,1,fp2);
        fwrite(&ihdr.biClrUsed,4,1,fp2);
        fwrite(&ihdr.biClrImportant,4,1,fp2);
    }else {
        printf("Image attribute infos:\n");
        printf("- image width:        %d pixels \n",ihdr.biWidth);
        printf("- image height:       %d pixels \n",ihdr.biHeight);
        printf("- image bit-count:    %d bits \n",ihdr.biBitCount);
        printf("- image compress:     %d \n",ihdr.biCompression);
        printf("- image horizon DPI:  %d pixels/meter \n",ihdr.biXPelsPerMeter);
        printf("- image vertical DPI: %d pixels/meter \n",ihdr.biYPelsPerMeter);
    }

    return dataSize;
}

void convert(FILE *fp1,FILE *fp2,int dataSize){

    int size = dataSize/3;
    int i;
    char R,G,B,Y;


    for (i=0;i<size;i++){
        fread(&B,1,1,fp1);
        fread(&G,1,1,fp1);
        fread(&R,1,1,fp1);
        Y = pow(pow(R,2.2) * 0.2126 + pow(G,2.2) * 0.7152 + pow(B,2.2) * 0.0722,1/2.2);
        fwrite(&Y,1,1,fp2);
        fwrite(&Y,1,1,fp2);
        fwrite(&Y,1,1,fp2);
    }

    printf("finished\n");
}

int main(int argc,char **argv)
{
    FILE *fp1, *fp2;
    int dataSize;
    int mode;

    if(argc == 1){
        printf("too few parameters\n");
        exit(-1);
    }else if (argc == 2){
        if (!strcmp(argv[1],"-h")){
            printf("BMP utils:\n");
            printf("----------------------------\n");
            printf("Usage:\n");
            printf("    bmp_utils -p bmp_file:\n");
            printf("    bmp_utils -c bmp_file:\n");
            exit(0);
        }else {
            printf("wrong parameter! \n please use -h to get more info");
            exit(-1);
        }
    }else if (argc != 3){
        printf("wrong parameter! \n please use -h to get more info");
        exit(-1);
    }

    if (strcmp(argv[1],"-p") && strcmp(argv[1],"-c")){
        printf("wrong parameter! \n please use -h to get more info");
        exit(-1);
    }

    mode = (strcmp(argv[1],"-p"))? 1:0;


    fp1 = fopen(argv[2],"rb");
    if(!fp1){
        printf("File open error");
        exit(-1);
    }

    if (mode){
        fp2 = fopen("proj2_gray.bmp","wb");
        if(!fp2){
            printf("File create error");
            exit(-1);
        }
    }

    dataSize = readinfo(fp1,fp2,mode);

    if(mode)convert(fp1,fp2,dataSize);

    fclose(fp1);
    if(mode)fclose(fp2);

    return 0;
}
